8

理解Actions

1.什么是actions

  • 背景:mutation中我们讲到,mutation中是存放处理数据的方法的集合,我们使用的时候需要commit。但是commit是同步函数,而且只能是同步执行。那我们想一步操作怎么办?

  • 作用:actions中提交mutation,并且可以包含任何的异步操作。actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据(但是还是通过mutation来操作,因为只有它能操作)


2.怎么用actions

  • 定义actions

    const store = new Vuex.Store({//创建store实例
          state: {
             count: 0
                 },
          mutations: {                
             increment (state) {
              state.count++
             }
              },
          actions: {         //只是提交`commit`了`mutations`里面的方法。
             increment (context) {
              context.commit('increment')
       }
     }
        })
       
      一般我们会简写成这样
      actions: {
       increment ({ commit }) {
             commit('increment')
          }
             }
  • 分发actions

     store.dispatch('increment')
  • MapActions和MapState一级MapMutations类似。


3.源码分析

  • registerAction():初始化action,和registerMutation类似,不同的地方是mutation是同步的修改当前模块的stateaction是可以异步的去修改。但是还是通过提交mutation来修改,必须明白在Vuex中只又mutation能修改state

    function registerAction (store, type, handler, path = []) {
      const entry = store._actions[type] || (store._actions[type] = [])
      //通过types拿到action的对象数组
      const { dispatch, commit } = store
      entry.push(function wrappedActionHandler (payload, cb) {
      //包装action成一个函数,payload表示载荷,并传入一个对象,
      let res = handler({ 
       dispatch,
       commit,
       getters: store.getters,
       state: getNestedState(store.state, path),
       rootState: store.state
      }, payload, cb)
     if (!isPromise(res)) {
     //如果不是promise对象,就包装成Promise对象,这也就是前面分析store的时候,断言函数要判断是否存在promise。
       res = Promise.resolve(res)
      }
     if (store._devtoolHook) {
       return res.catch(err => {
         store._devtoolHook.emit('vuex:error', err)
         throw err
       })
     } else {
       return res
     }
      })
      }
  • dispatch():分发actions

    dispatch (type, payload) {
      //判断type是否是对象类型
    if (isObject(type) && type.type) {
      payload = type
      type = type.type
    }
    const entry = this._actions[type]
    if (!entry) {
      console.error(`[vuex] unknown action type: ${type}`)
      return
    }
    return entry.length > 1
      ? Promise.all(entry.map(handler => handler(payload)))
      //在 action 的回调函数里,可以拿到当前模块的上下文包括 store 的 commit 和 dispatch 方法、getter、当前模块的 state 和 rootState
      : entry[0](payload)
      }

何凯
966 声望174 粉丝

Never too late to learn!